#include "adapt_prec_arith.h"
#include <queue>
#include <limits>

void split(double a, std::size_t s, double & a_h, double & a_l)
{
	double c = ((1LL << s) + 1LL) * a;
	double a_big = c - a;
	a_h = c - a_big;
	a_l = a - a_h;
}

double sum(double a, double b, double & roundoff)
{
	double s = a + b;
	double b_virt = s - a;
	double a_virt = s - b_virt;
	double b_roundoff = b - b_virt;
	double a_roundoff = a - a_virt;
	roundoff = a_roundoff + b_roundoff;
	return s;
}

double multiply(double a, double b, double & roundoff)
{
	double m = a * b;
	std::size_t s = std::numeric_limits<double>::digits / 2 + std::numeric_limits<double>::digits % 2;
	double a_h, a_l;
	split(a, s, a_h, a_l);
	double b_h, b_l;
	split(b, s, b_h, b_l);
	double e = m - (a_h * b_h) - (a_l * b_h) - (b_l * a_h);
	roundoff = a_l * b_l - e;
	return m;
}

int left_turn_apa(double a_x, double a_y, double b_x, double b_y, double c_x, double c_y)
{
	double mult[12];
	mult[0] = multiply(b_x, c_y, mult[1]);
	mult[2] = multiply((-1) * b_x, a_y, mult[3]);
	mult[4] = multiply((-1) * a_x, c_y, mult[5]);
	mult[6] = multiply((-1) * b_y, c_x, mult[7]);
	mult[8] = multiply(b_y, a_x, mult[9]);
	mult[10] = multiply(a_y, c_x, mult[11]);
	
	std::priority_queue<double> posit, negat;
	for (std::size_t i = 0; i < 12; i++)
	{
		if (mult[i] > 0)
			posit.push(mult[i]);
		if (mult[i] < 0)
			negat.push((-1) * mult[i]);
	}

	while(1)
	{
		std::size_t posit_s = posit.size();
		std::size_t negat_s = negat.size();
		if ((posit_s == 0) && (negat_s == 0))
		{
			return 0;
		}
		if (posit_s == 0)
		{
			return -1;
		}
		if (negat_s == 0)
		{
			return 1;
		}
		
		double a = posit.top();
		posit.pop();
		double b = negat.top();
		negat.pop();
		if (a == b)
		{
			continue;
		}
		if (a > 2 * negat_s * b)
		{
			return 1;
		}
		if (b > 2 * posit_s * a)
		{
			return -1;
		}
		double roundoff;
		double s = sum(a, (-1) * b, roundoff);
		if (s > 0)
		{
			posit.push(s);
		}
		if (s < 0)
		{
			negat.push((-1) *s);
		}
		if (roundoff > 0)
		{
			posit.push(roundoff);
		}
		if (roundoff < 0)
		{
			negat.push((-1) *roundoff);
		}
	}
}